package practise.mulitThreads.ConcurrentInPractice.binaryLatch;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by richard on 6/14/14.
 */
public class BinaryLatch {
    class Sync extends AbstractQueuedSynchronizer{
        AtomicBoolean canAcquire = new AtomicBoolean();
        Lock lock = new ReentrantLock();
        @Override
        protected boolean tryAcquire(int arg) {
            lock.lock();
            try{
            return canAcquire.getAndSet(!canAcquire.get());
            }
            finally {
                lock.unlock();
            }
        }

        @Override
        protected boolean tryRelease(int arg) {
            lock.lock();
            try{
                canAcquire.getAndSet(!canAcquire.get());
            }
            finally {
                lock.unlock();
            }
            return true;
        }
    }

    Sync sync = new Sync();
    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(0);
    }

    public void release(){
        sync.releaseShared(0);
    }
}
